package com.huan.es8.aggregations.metric;

import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.mapping.*;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.json.JsonData;
import com.huan.es8.AbstractEs8Api;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;

import java.io.IOException;
import java.util.Arrays;

/**
 * top hists 聚合
 * 需求：根据 `province`进行`terms`聚合，然后获取每个`terms`聚合 `age`最大的那个文档。
 *
 * <a href="https://blog.csdn.net/fu_huo_1993/article/details/128452306">博客</a>
 *
 * @author huan.fu
 * @date 2022/12/27 - 10:14
 */
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class TopHitsAggr extends AbstractEs8Api {

    // @BeforeAll
    public void createIndex() throws IOException {
        client.indices()
                .create(indexRequest ->
                        indexRequest.index("index_person")
                                .mappings(mappings ->
                                        mappings.properties("id", new Property(new LongNumberProperty.Builder().build()))
                                                .properties("name", new Property(new KeywordProperty.Builder().build()))
                                                .properties("age", new Property(new IntegerNumberProperty.Builder().build()))
                                                .properties("class", new Property(new TextProperty.Builder().fielddata(true).build()))
                                                .properties("province", new Property(new KeywordProperty.Builder().build()))
                                )
                );
        bulk("index_person", Arrays.asList(
                "{\"id\":1, \"name\":\"张三\",\"age\":18,\"class\":\"大一班\",\"province\":\"湖北\"}",
                "{\"id\":2, \"name\":\"李四\",\"age\":19,\"class\":\"大一班\",\"province\":\"湖北\"}",
                "{\"id\":3, \"name\":\"王武\",\"age\":20,\"class\":\"大二班\",\"province\":\"北京\"}",
                "{\"id\":4, \"name\":\"赵六\",\"age\":21,\"class\":\"大三班技术班\",\"province\":\"北京\"}",
                "{\"id\":5, \"name\":\"钱七\",\"age\":22,\"class\":\"大三班\",\"province\":\"湖北\"}"
        ));
    }

    @Test
    @DisplayName("top hits 聚合")
    public void test01() throws IOException {
        SearchRequest request = SearchRequest.of(searchRequest ->
                searchRequest.index("index_person")
                        .size(0)
                        .query(query -> query.range(range -> range.field("age").gt(JsonData.of(10))))
                        .aggregations("agg_01", agg ->
                                agg.terms(terms ->
                                                terms.field("province")
                                        )
                                        .aggregations("agg_02", subAgg ->
                                                subAgg.topHits(topHits ->
                                                        topHits.from(0)
                                                                .size(1)
                                                                .sort(sort -> sort.field(field -> field.field("age").order(SortOrder.Desc)))
                                                                .source(source -> source.filter(filter -> filter.includes(Arrays.asList("id", "age", "name"))))
                                                )
                                        )
                        )
        );
        System.out.println("request: " + request);
        SearchResponse<String> response = client.search(request, String.class);
        System.out.println("response: " + response);
    }

    // @AfterAll
    public void deleteIndex() throws IOException {
        deleteIndex("index_person");
    }
}
